using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

public class EventHandlerMgr
{
    private Dictionary<int, List<MsgHandler>> handlerDic;

    private static EventHandlerMgr instance = null;

    private EventHandlerMgr()
    {
        handlerDic = new Dictionary<int, List<MsgHandler>>();
    }
 

    public static EventHandlerMgr GetInstance()
    {
        if (null == instance)
        {
            instance = new EventHandlerMgr();
        }
        return instance;
    }

    /// <summary>
    /// 对外提供的注册监听的接口
    /// </summary>
 
    public void RegisterHandler(MsgHandler handler, params EventName[] EventNames)
    {
        for (int i = 0; i < EventNames.Length; i++)
        {
            RegisterHandler(EventNames[i], handler);
        }
    }

    /// <summary>
    /// 内部实际调用的注册监听的方法
    /// </summary>
    private void RegisterHandler(EventName type, MsgHandler handler)
    {
        if (null != handler)
        {
            if (!handlerDic.ContainsKey((int)type))
            {
                handlerDic.Add((int)type, new List<MsgHandler>());
            }
            if (!handlerDic[(int)type].Contains(handler))
            {
                handlerDic[(int)type].Add(handler);
            }
        }
    }

    /// <summary>
    /// 反注册事件监听的接口，对所有类型的事件移除指定的监听
    /// </summary>
    /// <param name="handler"></param>
    public void UnRegisterHandler(MsgHandler handler)
    {
        using (var enumerator = handlerDic.GetEnumerator())
        {
            List<MsgHandler> list;
            while (enumerator.MoveNext())
            {
                list = enumerator.Current.Value;
                list.Remove(handler);
            }
        }
    }

    /// <summary>
    /// 反注册事件监听的接口，移除指定类型事件的监听
    /// </summary>
    public void UnRegisterHandler(MsgHandler handler, params EventName[] types)
    {
        EventName type;
        for (int i = 0; i < types.Length; i++)
        {
            type = types[i];
            if (handlerDic.ContainsKey((int)type) && handlerDic[(int)type].Contains(handler))
            {
                handlerDic[(int)type].Remove(handler);
            }
        }
    }

    /// <summary>
    /// 分发事件
    /// </summary>
    /// <param name="gameEvent"></param>想要分发的事件
    public void DispatchEvent(GameEvent gameEvent)
    {

        List<MsgHandler> handlers;
        if (null != gameEvent && handlerDic.TryGetValue((int)gameEvent.EventName, out handlers))
        {
            for (int i = 0; i < handlers.Count; i++)
            {
                try
                {
                    handlers[i](gameEvent.ParaList);
                }
                catch (Exception e)
                {
                    Debug.LogError(e);
                }
            }
        }
        else
        {
            if (null != gameEvent)
            {
                switch (gameEvent.EventName)
                {
                    default:
                        Debug.LogError("消息未处理，事件名：" + gameEvent.EventName);
                        break;
                }
            }
        }
    }

   /// <summary>
   /// 分发事件
   /// </summary>
   /// <param name="evt">事件名</param>
   /// <param name="EventName">事件类型</param>
   /// <param name="para">参数</param>
    public void DispatchEvent(EventName EventName = EventName.InputMsg, params object[] para)
    {
        GameEvent gameEvent = new GameEvent();
        gameEvent.EventName = EventName;
        if (null != para)
        {
            gameEvent.ParaList = new List<object>();
            for (int i = 0; i < para.Length; i++)
            {
                gameEvent.ParaList.Add(para[i]);
            }
        }

        this.DispatchEvent(gameEvent);
    }

    /// <summary>
    /// 分发事件
    /// </summary>
    /// <param name="evt"></param>分发的消息名称
    /// <param name="EventName"></param>消息事件类型
    public void DispatchEvent(EventName EventName = EventName.InputMsg)
    {
        GameEvent gameEvent = new GameEvent();
        gameEvent.EventName = EventName;
        gameEvent.ParaList = null;
        this.DispatchEvent(gameEvent);
    }
}
